﻿using System;
using System.Collections;
using System.Data;
using System.Configuration;
using System.Web;
using System.Xml;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Rookey.Frame.IMCore.IO;
using System.Threading;
using System.Drawing;
using System.Drawing.Imaging;
using Rookey.Frame.IMCore;

/// <summary>
///DownloadHandler 的摘要说明
/// </summary>
namespace Rookey.Frame.IMWeb
{
	public class DownloadHandler : IHttpHandler
	{
		static Hashtable ContentType = new Hashtable();

		static DownloadHandler()
		{
			ContentType[".JS"] = "application/x-javascript";
			ContentType[".XML"] = "text/xml";
			ContentType[".HTML"] = "text/html";
			ContentType[".HTM"] = "text/html";
			ContentType[".CSS"] = "text/css";
			ContentType[".TXT"] = "text";
			ContentType[".PNG"] = "image";
			ContentType[".BMP"] = "image";
			ContentType[".GIF"] = "image";
			ContentType[".JPG"] = "image";
			ContentType[".ICO"] = "image";
			ContentType[".CUR"] = "image";
		}

		public DownloadHandler()
		{
		}

		void IHttpHandler.ProcessRequest(HttpContext context)
		{
			string fileName = "";
			if (System.IO.Path.GetFileName(context.Request.Url.AbsolutePath).ToLower() == "headimg.aspx")
			{
				string user = context.Request.QueryString["user"];
				int size = Convert.ToInt32(context.Request.QueryString["size"] ?? "0");
				bool gred = Convert.ToBoolean(context.Request.QueryString["gred"] ?? "false");

				AccountInfo userInfo = AccountImpl.Instance.GetUserInfo(user);

				string preFileName = userInfo.HeadIMG;

				if (!Rookey.Frame.IMCore.IO.File.Exists(preFileName)) preFileName = String.Format("/{0}/Public/Images/HeadImg/{1}.png", userInfo.Name, userInfo.Type == 0 ? "user" : "group");

				fileName = preFileName;
				if (gred) fileName += ".gred";
				if (size > 0) fileName += String.Format(".{0}", size);
				if (fileName != preFileName)
				{
					fileName += ".png";
					if (!Rookey.Frame.IMCore.IO.File.Exists(fileName))
					{
						fileName = ZoomHeadImage(preFileName, fileName, size, size, gred);
					}
				}
			}
			else
			{
				fileName = ServerImpl.Instance.GetFullPath(context, context.Request["FileName"]);
			}
			ServerImpl.Instance.CheckPermission(context, fileName, IOPermission.Read);

			using (System.IO.Stream stream = File.Open(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
			{
				try
				{
					string ext = Path.GetExtension(fileName).ToUpper();
					if (ContentType.ContainsKey(ext))
					{
						context.Response.ContentType = ContentType[ext] as string;
						context.Response.AppendHeader("Content-Disposition", string.Format("filename={0}", Microsoft.JScript.GlobalObject.escape(Path.GetFileName(fileName))));
					}
					else
					{
						context.Response.ContentType = "application/octet-stream";
						context.Response.AppendHeader("Content-Disposition", string.Format("attachment;filename={0}", Microsoft.JScript.GlobalObject.escape(Path.GetFileName(fileName))));
					}


					FileSystemInfo fileInfo = new FileInfo(fileName);
					if (fileInfo != null)
					{
						context.Response.AppendHeader("Last-Modified", String.Format("{0:R}", fileInfo.LastWriteTime));
					}

					context.Response.AppendHeader("Content-Length", stream.Length.ToString());

					byte[] buffer = new byte[4 * 1024];
					while (true)
					{
						int c = stream.Read(buffer, 0, buffer.Length);
						if (c == 0) break;
						context.Response.OutputStream.Write(buffer, 0, c);
					}
				}
				finally
				{
					stream.Close();
				}
			}
		}

		bool IHttpHandler.IsReusable
		{
			get { return true; }
        }

        private static string ZoomHeadImage(String headImg, String targetImg, int width, int height, bool gred)
        {
            Bitmap zoomImg = null;
            using (System.IO.Stream stream = Rookey.Frame.IMCore.IO.File.Open(headImg, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
            {
                Bitmap img = new Bitmap(stream);
                if (width > 0 && height > 0 && (img.Width > width || img.Height > height || stream.Length > 20 * 1024))
                {
                    if (System.IO.Path.GetExtension(targetImg).ToLower() != ".png") targetImg += ".png";

                    int newWidth, newHeight;
                    if (img.Width * height > img.Height * width)
                    {
                        newWidth = width;
                        newHeight = img.Height * width / img.Width;
                    }
                    else
                    {
                        newHeight = height;
                        newWidth = img.Width * height / img.Height;
                    }
                    zoomImg = new Bitmap(img, new Size(newWidth, newHeight));
                    if (gred) zoomImg = Rookey.Frame.IMCore.Utility.ToGray(zoomImg, 0);
                }
                else
                {
                    if (gred)
                    {
                        zoomImg = Rookey.Frame.IMCore.Utility.ToGray(img, 0);
                    }
                    else
                    {
                        zoomImg = img;
                    }
                }
            }

            using (System.IO.Stream target_stream = Rookey.Frame.IMCore.IO.File.Open(targetImg, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None))
            {
                Bitmap t_img = new Bitmap(width, height);
                Graphics graphics = Graphics.FromImage(t_img);
                graphics.FillRectangle(Brushes.White, new Rectangle(0, 0, width, height));
                graphics.DrawImage(zoomImg, (width - zoomImg.Width) / 2, (height - zoomImg.Height) / 2);
                t_img.Save(target_stream, ImageFormat.Png);
            }

            return targetImg;
        }
	}
}